package org.gnomus.server.controllers;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Transaction;
import org.gnomus.data.*;
import org.gnomus.server.Context;
import org.gnomus.server.Controller;
import org.gnomus.util.json;

import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Teach implements Controller {
    public String id;
    public String group_json;
    public String name;
    public String lab;
    public String group_id;

    public boolean landing() {
        Context ctx = Context.get();
        if (!ctx.us.isUserLoggedIn()) {
            ctx.redirect(ctx.us.createLoginURL("/teach"));
            return false;
        }
        List<group> groups = group.fetch(ctx.acnt.key);
        for (group grp : groups) {
            grp.put("members", grp.getMembers());
            grp.put("assignments", grp.getAssignments());
        }
        ctx.data.put("groups", groups);
        return true;
    }

    public boolean assignment() {
        assert id != null;
        assignment ant = new assignment(store.get("assignment", id));
        Context.get().data.put("assignment", ant);
        return true;
    }

    public boolean createGroup() {
        assert name != null;
        Context ctx = Context.get();
        boolean valid = true;
        for (group grp : group.fetch(ctx.acnt.key)) {
            if (name.equals(grp.getName())) { valid = false; break; }
        }
        if (valid) {
            group grp = new group(name);
            grp.save();
            link lnk = new link(ctx.acnt.kind, ctx.acnt.key, grp.kind, grp.key);
            lnk.save();
        }
        try {
            String s = valid ? "Group '" + name + "' created successfully." : "A group with that name already exists.";
            ServletOutputStream out = ctx.res.getOutputStream();
            out.write(s.getBytes());
            out.flush();
            return true;
        } catch (IOException e) {
            throw new Error(e);
        }
    }

    public boolean updateGroup() {
        assert group_json != null;
        Object j = json.decode(group_json);
        if (j instanceof Map) {
        group grp = new group(store.get("group", (String) ((Map) j).get("id")));
            Object m = ((HashMap) j).get("members");
            if (m instanceof List) {
                grp.updateMembers((List<Map>) m);
            }
        }
        return true;
    }

    public boolean deleteGroup() {
        assert id != null;
        Context ctx = Context.get();
        group grp = new group(store.get("group", id));
        link.delete(grp.key);
        store.delete(grp.key);
        return true;
    }

    public boolean createAssignment() {
        assert group_id != null;
        assert lab != null;
        group grp = new group(store.get("group", group_id));
        for (link lnk : link.fetch(grp.kind, grp.key, "assignment", null)) {
            assignment acs = new assignment(store.get(lnk.getTargetKey()));
            if (lab.equals(acs.getLab())) {
                try {
                    ServletOutputStream out = Context.get().res.getOutputStream();
                    out.write("You've already assigned this lab to this group.".getBytes());
                    out.flush();
                    return true;
                } catch (IOException e) {
                    throw new Error(e);
                }
            }
        }
        assignment ant = new assignment(lab);
        ant.save();
        link lnk = new link(grp.kind, grp.key, ant.kind, ant.key);
        lnk.save();
        for(member mbr : grp.getMembers()) {
            if (mbr.isActive()) {
                access acs = new access(mbr, ant);
                acs.save();
            }
        }
        return true;
    }
}
